﻿using System.Net;
using System.IO;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using FacebookWrapper;
using FacebookWrapper.ObjectModel;

namespace C12_Ex03_Shaked_032675316_Itay_032511057
{
    public delegate void UserRelatedAction(User i_User);

    public partial class FormMain : Form
    {
        public const int k_AutoStalkMaxPhotoDownloadPerFriend = 10;
        public const int k_MaxAmountOfWallPostsToDisplay = 5;

        private User m_LoggedinUser;
        private User m_SelectedUser;
        private DownloadGalleries m_DownloadGalleries;
        private FacebookImageMapper m_ImageMapper;
        private LoadingForm m_loadingFrom;

        private ContextMenu m_PictureUploadNotifications;

        public FormMain()
        {
            InitializeComponent();

            m_PictureUploadNotifications = new ContextMenu();
            wallMessagePoster.Post += showWallPosts;

            m_DownloadGalleries = new DownloadGalleries();
            TabGalleryDownload.Controls.Add(m_DownloadGalleries);
        }

        private void login()
        {
            FacebookWrapper.FacebookService.s_CollectionLimit = 100;
            LoginResult result = FacebookWrapper.FacebookService.Login("144230912382769", "publish_stream", "user_status", "friends_status", "user_photos", "friends_photos", "read_stream", "user_location", "friends_location", "user_hometown", "friends_hometown", "user_birthday", "friends_birthday", "email");

            if (result.LoggedInUser != null)
            {
                m_LoggedinUser = result.LoggedInUser;
                SplitDisplay.Visible = true;
                reload();

                m_ImageMapper = new FacebookImageMapper(m_LoggedinUser);
                ButtonPictureNotifier.Numerator = m_ImageMapper.NewPicturesCount;
                m_PictureUploadNotifications.MenuItems.Clear();

                if (m_ImageMapper.NewPicturesCount > 0)
                {
                    foreach (User user in m_ImageMapper.UsersWithNewPictures)
                    {
                        MenuItem item = new MenuItem(user.Name + " has uploaded some new pictures");
                        item.Click += delegate(object i_Sender, EventArgs i_EventArgs)
                        {
                            m_SelectedUser = user;
                            activateSelectedUser();
                            tabControl1.SelectedIndex = 2;
                            m_PictureUploadNotifications.MenuItems.Remove(item);
                            ButtonPictureNotifier.Numerator--;
                        };
                        m_PictureUploadNotifications.MenuItems.Add(item);
                    }
                }
            }
        }

        private void ButtonLogin_Click(object sender, EventArgs e)
        {
            login();
        }

        private void reload()
        {
            if (m_LoggedinUser != null)
            {
                assignUserData(m_LoggedinUser);
                populateFriendsListBox(m_LoggedinUser.Friends);
                wallMessagePoster.User = m_LoggedinUser;
                showWallPosts(m_LoggedinUser);
                showInfo(m_LoggedinUser);
                showDownloadGalleries(m_LoggedinUser);
            }
        }

        private void showDownloadGalleries(User i_User)
        {
            m_DownloadGalleries.UserName = i_User.Name.ToString();
            m_DownloadGalleries.Albums = i_User.Albums;
        }

        private void showInfo(User i_User)
        {
            LabelName.Text = i_User.Name;
            LabelGender.Text = i_User.Gender.GetValueOrDefault().ToString();
            LabelBirthday.Text = i_User.Birthday != null ? i_User.Birthday : string.Empty;

            LabelHometown.Text = i_User.Hometown != null ? i_User.Hometown.Name : string.Empty;
            LabelLocation.Text = i_User.Location != null ? i_User.Location.Name : string.Empty;

            pictureInfoProfilePic.LoadAsync(i_User.PictureNormalURL);

            LabelEmail.Text = i_User.Email;
        }

        private void assignUserData(User i_User)
        {
            LabelUsername.Text = i_User.Name;

            PictureUser.LoadAsync(i_User.PictureSqaureURL);
        }

        private void populateFriendsListBox(FacebookObjectCollection<User> i_Friends)
        {
            foreach (User friend in i_Friends)
            {
                ListBoxFriends.Items.Add(friend);
            }
        }

        private void commentPosted()
        {
            ButtonReload_Click(null, null);
        }

        private void showWallPosts(User i_User)
        {
            PanelWallPosts.Controls.Clear();
            for (int i = 0; i < i_User.WallPosts.Count && i < k_MaxAmountOfWallPostsToDisplay; i++)
            {
                Post post = i_User.WallPosts[i];
                WallPost wallPost = new WallPost()
                {
                    CommentPostedAction = new Action(commentPosted),
                    Post = post,
                    Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right,
                    Width = PanelWallPosts.Width
                };

                PanelWallPosts.Controls.Add(wallPost);
            }

            PanelWallPosts.AutoScrollPosition = Point.Empty;
        }

        private void ListBoxFriends_DoubleClick(object sender, EventArgs e)
        {
            User selectedUser = ListBoxFriends.Items[ListBoxFriends.SelectedIndex] as User;
            if (selectedUser != null)
            {
                m_SelectedUser = selectedUser;
                activateSelectedUser();
            }
        }

        private void activateSelectedUser()
        {
            if (m_SelectedUser != null)
            {
                wallMessagePoster.User = m_SelectedUser;
                showWallPosts(m_SelectedUser);
                showInfo(m_SelectedUser);
                showDownloadGalleries(m_SelectedUser);

                ButtonActivateNotifications.Enabled = !m_ImageMapper.IsFriendMapped(m_SelectedUser);

                if (m_ImageMapper.IsFriendMapped(m_SelectedUser))
                {
                    FacebookImageMapperToGalleryDisplayAdapter adapter = new FacebookImageMapperToGalleryDisplayAdapter(m_ImageMapper, m_SelectedUser);
                    galleryDisplay1.Images = adapter;
                }
            }
        }

        private void ButtonReload_Click(object sender, EventArgs e)
        {
            User selectedUser = m_SelectedUser;
            ButtonLogin_Click(sender, e);
            m_SelectedUser = selectedUser;
            activateSelectedUser();
        }

        private void ButtonToggleFriends_Click(object sender, EventArgs e)
        {
            SplitDisplay.Panel1Collapsed = !SplitDisplay.Panel1Collapsed;
            SplitDisplay.Panel1.Enabled = !SplitDisplay.Panel1.Enabled;
        }

        private void ButtonActivateNotifications_Click(object sender, EventArgs e)
        {
            m_ImageMapper.AddOrUpdateFriendImages(m_SelectedUser);
            ButtonActivateNotifications.Enabled = false;
        }

        private void ButtonPictureNotifier_Click(object sender, EventArgs e)
        {
            m_PictureUploadNotifications.Show(ButtonPictureNotifier, new Point(0, ButtonPictureNotifier.Height));
        }

        private void ButtonAutoStalk_Click(object sender, EventArgs e)
        {
            AutoStalk();
            this.Invoke(new Action(() => this.Close()));
        }

        private void AutoStalk()
        {
            m_loadingFrom = new LoadingForm();
            m_loadingFrom.Location = new Point(this.Location.X + 100, this.Location.Y + 100);
            login();
            Thread AutoStalkThread = new Thread(new ThreadStart(autoStalkCallBack));
            AutoStalkThread.Start();
            m_loadingFrom.ShowDialog();
        }

        private void downloadUserPhotos(User i_Friend)
        {
            int numOfPhotosOfDownloaded = 0;
            if (i_Friend.Gender.HasValue && i_Friend.Gender.Value.Equals(FacebookWrapper.ObjectModel.User.eGender.female))
            {
                string downloadFolder = DownloadGalleries.r_DefaultDownloadPath + Path.DirectorySeparatorChar + i_Friend.Name.SafeFileNameString();
                m_loadingFrom.CurrentUserName = i_Friend.Name;
                foreach (Album albumToDownload in i_Friend.Albums)
                {
                    foreach (Photo photo in albumToDownload.Photos)
                    {
                        IFaceBookGalleriesDownloadHandler downloadHandlerInstance = FaceBookGalleriesDownloadHandler.Instance;
                        downloadHandlerInstance.DownloadImage(photo.URL, albumToDownload.Name, downloadFolder);
                        numOfPhotosOfDownloaded++;
                        if (k_AutoStalkMaxPhotoDownloadPerFriend <= numOfPhotosOfDownloaded)
                        {
                            throw new AutoStackTooManyPhotoDownloadsException();
                        }
                    }
                }
            }
        }

        private void autoStalkCallBack()
        {
            if (m_LoggedinUser != null)
            {
                foreach (User friend in m_LoggedinUser.Friends)
                {
                    try
                    {
                        downloadUserPhotos(friend);
                    }
                    catch (AutoStackTooManyPhotoDownloadsException e)
                    {
                        MessageBox.Show("An Error has occured: " + e.Message);
                    }
                }

                m_loadingFrom.CurrentUserName = string.Empty;
            }

            m_loadingFrom.Invoke(new Action(() => m_loadingFrom.Close()));
        }
    }
}
